/** @file */
#include "stdafx.h"

#ifndef _SoundPlayer_h_
#define _SoundPlayer_h_

#include <fmod.hpp>
#include <fmod_errors.h>
#include <map>
#include <fmod_event.hpp>
#include "QueuedSound.h"
#include <list>
#include "Sound.h"
#include "SoundPlayer.h"
#include <math.h>
#include <list>



/** @class SoundPlayer
 *
 *  @brief A singleton class interfacing with FMOD to play music and sounds
 *	
 *	@author Simulation engines 2012 group 3
* 
*/
class SoundPlayer
{
	


public:

	/**
	* @brief Get the Singleton instance
	*
	* 
	*/
	static SoundPlayer* getInstance();
	/**
	* @brief Destroy the Singleton instance
	*
	* Destroy the instance and delete all FMOD stuff
	*/
	static void destroyInstance();

	/**
	* @brief Update the underlying FMOD engine
	* 
	* Needed to be called once per frame make sure music and parameter-based events work correctly
	*/
	void update(float deltaTime);
	/**
	* @Change a music parameter
	*
	*  @param paramName paramater name
	*
	*  @param paramValue parameter value
	*
	* Changes a music parameter, such as tension
	*/
	void changeMusicParameter(unsigned int paramId, float paramValue);
	/**
	* @brief activate a musical cue
	*
	* 
	*/
	void activateCue(unsigned int cueId);
	/**
	* @brief deactivate a musical cue
	*
	* 
	*/
	void deactivateCue(unsigned int cueId);
	/**
	* @brief activate a oneshot sound event (in essence, play a sound)
	*
	* 
	*/
	void activateEvent(unsigned int eventId);
	/**
	* @brief activate a oneshot 3d sound event (in essence, play a 3d sound)
	*
	* 
	*/
	void activateEvent3d(unsigned int eventId, float x, float y, float z);

	/**
	* @brief Update the position of the 3D listener
	*
	* Use this function to change the orientation and location of the "microphone" or listener
	* px,py,pz = position vector
	* vx,vy,vz = velocity vector
	* fx,fy,fz = forward vector
	* ux,uy,uz = up vector
	*/
	void update3dListener(float px, float py, float pz, float vx, float vy,float vz,float fx,float fy,float fz,float ux,float uy,float uz );
	/**
	* @brief Get the FMOD event of a certain ID
	*
	* Used by the Sound class, should not be used by other classes
	* 
	*/
	FMOD::Event* getEvent(unsigned int eventId);
	/**
	* @brief Reset the timer used for playing events in sync with music
	*
	* This function is unneccesary to call since synced events are not yet possible in FMOD
	*/
	void resetMusicTimer();


	/**
	* @brief Set a sound to play at the next beat
	*
	*  @param sound Sound to play
	*
	*  @param bpm Tempo, in BPM, that determines when the first beat will occur.
	*
	* This function is unneccesary to call since synced events are not yet possible in FMOD
	*/
	void queueToNextBeat(Sound* sound, float bpm);
	/**
	* @brief Reset the FMOD music system
	*
	* Call this function when stopping music
	*/
	void resetMusic();



protected:

private:

	/**
	* @brief Private Singleton constructor
	*
	* 
	*/
	SoundPlayer();
	/**
	* @brief Private Singleton destructor
	*
	* details
	*/
	~SoundPlayer();
	/**
	* @brief Initialize the soundplayer
	*
	* details
	*/
	int initialize();
	/**
	* @brief Checks for errors when using FMOD functions
	*
	* 
	*/
	void errcheck(FMOD_RESULT result);
	/**
	* @brief 
	* Checks if the music timer is on a beat this frame
	* 
	*/
	bool isOnBeat(float bpm);

	
	static SoundPlayer* theInstance;
	//music and event system
	FMOD::EventSystem	*m_system;
	FMOD::MusicSystem* m_musicSystem;
	
    FMOD_RESULT       m_result;
    unsigned int      m_version;
	//Map for prompts
	std::map<int, FMOD::MusicPrompt*>* m_promptMap;
	//std::map<int, FMOD::Event*>* m_eventMap;
	float			m_timePassed;
	float			m_lastTimeDelta; //Use averaging instead of just last time delta?
	//A list of all queued sound to play at the next beat
	std::list<QueuedSound*>* m_queuedList;



	
	

};


#endif //_SoundPlayer_h_

